#include "Vector3.h"
//Vec3 and Mat33 are the basic types used by scythe, that you will need to define
//here we just typedef to our own math classes
typedef Scythe::Vector3 Vec3;
typedef Scythe::Matrix Mat33;
//Otherwise, use the 2 below
//typedef float Vec3[3];
//typedef Vec3 Mat33[3];

#include <includePhysX.h>
#include "physLoadSave.h"
#include "nxutility.h"

#include <stdio.h>										// Header File For Standard Input / Output
#include <stdarg.h>									// Header File For Variable Argument Routines
#include <math.h>
#include <string>
#include <stdlib.h.>
#include <vector>
using namespace std;
using std::string;
#include <fstream>

namespace Scythe
{
//Callback function definitions
typedef void (*pfnJoint)(NxJoint*, const PhysicsJoint*);
typedef void (*pfnBody)(NxActor*, const PhysicsActor*);
typedef void (*pfnModel)(const char*, const PhysicsModel*, const int);
typedef void (*pfnLight)(const PhysicsLight*, const int);

//each rigidbody is listed in one of these
class ModelOffset
{
public:
	int			id;				//our index in the PhysicsClass::actors list
	Vector3		offsetPos;		//positional offset for each model.  model position = rigidbody position + modelPos
	Matrix		offsetMat;		//offset from rigidbody's rotation
	int			rigidbody;			//the actual physics engine's rigidbody pointer
};

/*
The physics engine control system
*/
class PhysicsClass
{
public:
	PhysicsClass();
	~PhysicsClass();

	//Actors have models attached to them.  Whenever a model is supposed to be loaded,
	//it will call this function and it will be up to you to load the appropriate model
	//it is optional, however without it you will only have physics, and no visuals
	void setLoadModelCallback(pfnModel func);
	void setLoadLightCallback(pfnLight func);

protected:
	pfnModel	modelCallback;
	pfnLight	lightCallback;
	vector<ModelOffset*>	models;
};
/*
class PhysXClass : public PhysicsClass
{
public:
	PhysXClass();
	~PhysXClass();

	void		setup(NxPhysicsSDK* physicsSdk, bool hardware, const char* rootPath);
	std::string	pathRoot;
	bool		HW;		//indicates if we are using hardware physics
	
	bool		insert(NxScene* world, const PhysicsEntity* physEnt, const Vector3 position, pfnBody bodyCallbackOverride = 0, pfnJoint jointCallbackOverride = 0);
	bool		insert(NxScene* world, const PhysicsEntity* physEnt, const Vector3 position, const Quat rotation, pfnBody bodyCallbackOverride = 0, pfnJoint jointCallbackOverride = 0);
	bool		insert(NxScene* world, const PhysicsEntity* physEnt, const Vector3 position, const Matrix rotation, pfnBody bodyCallbackOverride = 0, pfnJoint jointCallbackOverride = 0);
	bool		insertT(NxScene* world, const PhysicsEntity* physEnt, const Vector3 position, const Matrix rotation, pfnBody bodyCallbackOverride = 0, pfnJoint jointCallbackOverride = 0);		//transposed matrix
	void		clearSim();

	//this is called after a new rigidbody is created, it is optional,
	//and is there to allow you to store the rigidbody pointer if you wish,
	//or make any changes to it
	void setBodyCreatedCallback(pfnBody func);
	//this is the same as the body callback, except for joints
	//also optional
	void setJointCreatedCallback(pfnJoint func);

	//update functions
	Vector3	getModelPos(int id);
	Matrix	getModelRotRows(int id);
	Matrix	getModelRotColumns(int id);
	Quat		getModelRotQuat(int id);

private:

	pfnJoint	jointCallback;
	pfnBody		bodyCallback;
	
	NxActor*	createNewActor(const PhysicsActor* act, const Vector3 position, NxScene* nxScene, const Matrix rotation, pfnBody bodyCallbackOverride);		//returns index
	void		createBaseShape(const PhysicsPrimitive* primitive, NxShapeDesc* shape, const PhysicsActor* act);
	void		createJoint(const PhysicsJoint* joint, NxActor* act0, NxActor* act1, NxScene* nxScene, const Vector3 positionOffset, const Matrix rotation, pfnJoint jointCallbackOverride);
	void		createJointHW(const PhysicsJoint* joint, NxActor* act0, NxActor* act1, NxScene* nxScene, const Vector3 positionOffset, const Matrix rotation, pfnJoint jointCallbackOverride);
	void		createJointBase(const PhysicsJoint* joint, NxJointDesc* desc, NxActor* act0, NxActor* act1, const Vector3 jointPos, const Vector3 jointDir);

	void		SetActorGroup(const NxActor *actor, NxCollisionGroup group);	//this handy function sets the group of a whole actor

	vector<NxActor*> obj;
	NxPhysicsSDK*	physicsSDK;
};
*/
}
/**/